package cn.edu.swu.miniwebsvr.core;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Server {
    private final Config config = Config.getInstance();
    private final ExecutorService threadPool = Executors.newFixedThreadPool(10);
    private volatile boolean isRunning = true;

    public void start() {
        try (ServerSocket serverSocket = new ServerSocket(config.getPort())) {
            // 使用英文输出
            System.out.println("MiniWebSvr started successfully on port: " + config.getPort());
            System.out.println("Web root directory: " + config.getWebRoot());
            System.out.println("Server is running... Press Ctrl+C to stop");

            while (isRunning) {
                try {
                    Socket clientSocket = serverSocket.accept();
                    System.out.println("New connection from: " + clientSocket.getInetAddress().getHostAddress());
                    threadPool.execute(new RequestProcessor(clientSocket));
                } catch (IOException e) {
                    if (isRunning) {
                        System.err.println("Error accepting client connection: " + e.getMessage());
                    }
                }
            }
        } catch (IOException e) {
            System.err.println("Server startup failed: " + e.getMessage());
            e.printStackTrace();
        } finally {
            stop();
        }
    }

    /**
     * 停止服务器
     */
    public void stop() {
        isRunning = false;
        threadPool.shutdown();
        System.out.println("Server stopped");
    }

    private static class RequestProcessor implements Runnable {
        private final Socket socket;

        public RequestProcessor(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            try {
                // 设置socket超时时间，防止长时间阻塞
                socket.setSoTimeout(30000); // 30秒超时

                // 解析HTTP请求
                Parameter request = HttpParser.parse(socket.getInputStream());

                // 记录请求日志
                if (request != null && request.getMethod() != null && request.getUrl() != null) {
                    System.out.println("Processing request: " + request.getMethod() + " " + request.getUrl());
                }

                // 路由处理
                Router router = new Router();
                router.route(request, socket.getOutputStream());

            } catch (Exception e) {
                System.err.println("Request processing error: " + e.getMessage());
                sendErrorResponse(500, "Internal Server Error", "Server error: " + e.getMessage());
            } finally {
                // 确保socket资源被关闭
                closeSocket();
            }
        }

        /**
         * 发送错误响应
         */
        private void sendErrorResponse(int statusCode, String statusText, String message) {
            try {
                java.io.OutputStream output = socket.getOutputStream();
                java.io.PrintWriter writer = new java.io.PrintWriter(output);

                writer.println("HTTP/1.1 " + statusCode + " " + statusText);
                writer.println("Content-Type: text/html; charset=utf-8");
                writer.println("Connection: close");
                writer.println();

                writer.println("<!DOCTYPE html>");
                writer.println("<html>");
                writer.println("<head>");
                writer.println("    <title>" + statusCode + " " + statusText + "</title>");
                writer.println("    <meta charset=\"utf-8\">");
                writer.println("</head>");
                writer.println("<body>");
                writer.println("    <h1>" + statusCode + " " + statusText + "</h1>");
                writer.println("    <p>" + message + "</p>");
                writer.println("</body>");
                writer.println("</html>");

                writer.flush();
            } catch (IOException e) {
                System.err.println("Error sending error response: " + e.getMessage());
            }
        }

        /**
         * 安全关闭socket连接
         */
        private void closeSocket() {
            if (socket != null && !socket.isClosed()) {
                try {
                    socket.close();
                } catch (IOException e) {
                    System.err.println("Error closing socket: " + e.getMessage());
                }
            }
        }
    }

    /**
     * 主方法 - 启动服务器
     */
    public static void main(String[] args) {
        Server server = new Server();

        // 添加关闭钩子，确保程序退出时资源被正确释放
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            System.out.println("\nShutting down server...");
            server.stop();
        }));

        // 启动服务器
        server.start();
    }
}